<template>
  <div class="layout_one">
    <el-button type="primary" @click="startRecord">开始录制</el-button>
    <el-button type="primary" @click="pauseRecord">暂停录制</el-button>
    <el-button type="primary" @click="stopRecord">保存</el-button>
    <el-button type="primary" @click="playRecord">播放</el-button>
    <el-button type="primary" @click="screenshot">截图</el-button>

    <video
      controls
      autoplay
      playsinline
      ref="videoRef"
      width="900"
      height="600"
    />

    <canvas ref="canvasRef" />
  </div>
</template>
    
<script lang="ts">
import { defineComponent, reactive, toRefs } from "vue";
import { useRouter } from "vue-router";
import RecordRTC from "recordrtc";

export default defineComponent({
  name: "RecordRTC",
  setup() {
    const state = reactive({
      videoStream: {} as MediaStream,
      videoRef: {} as HTMLMediaElement,
      isRecord: false,
      isPaused: false,
      recorder: {} as any,
      canvasRef: {} as any,
    });

    const router = useRouter();

    // 开始录制
    const startRecord = () => {
      if (!state.isRecord) {
        navigator.mediaDevices
          .getDisplayMedia({
            video: {
              width: 3840,
              height: 2160,
              frameRate: 60,
            },
            audio: true,
          })
          .then(async (stream) => {
            addStreamStopListener(stream, () => {});
            state.videoStream = stream;
            // 把流赋值给video 实现实时录制
            state.videoRef.srcObject = stream;
            state.recorder = RecordRTC(stream, {
              type: "video",
              mimeType: "video/webm;codecs=vp9", // 视频类型
              recorderType: RecordRTC.MediaStreamRecorder,
              timeSlice: 1000, // 获取基于间隔的blob值（以毫秒为单位）
              disableLogs: true, // 禁用日志
              // 获取时间片段的时间戳
              onTimeStamp: (timestamp: any) => {
                console.log("timestamp", timestamp);
              },
              // 该回调函数必须和上面的timeSlice分片时间配合使用
              ondataavailable: (blob: any) => {
                // blob为每一秒的视频片段
                console.log("blob", blob);
              },
              bitsPerSecond: 128000,
            });
            // 开启录制
            state.recorder.startRecording();
            state.isRecord = true;

            // const sleep = (m: any) => new Promise((r) => setTimeout(r, m));
            // await sleep(10000);
            // // 十秒后结束视频录制
            // state.recorder.stopRecording((audioURL: any) => {
            //   // window.open(audioURL)
            //   close();
            // });
          })
          .catch((err) => {
            console.log("用户未开启视频权限");
          });
      }
    };

    // 暂停录制
    const pauseRecord = () => {
      if (state.isRecord && !state.isPaused) {
        state.recorder.pauseRecording();
        state.isPaused = true;
      } else if (state.isRecord && state.isPaused) {
        state.recorder.resumeRecording();
        state.isPaused = false;
      }
    };

    // 停止录制
    const stopRecord = () => {
      state.videoRef.srcObject = null;
      /*---------------------初始写法---------------------*/
      // state.recorder.stopRecording((blobURL: any) => {
      //   console.log("blobURL", blobURL);

      //   let blob = state.recorder.getBlob();
      //   console.log("blob", blob);
      //   console.log("state.recorder.blob", state.recorder.blob);
      //   // let file = new File([blob], "xxx.mkv");
      //   // console.log(file);
      //   RecordRTC.invokeSaveAsDialog(blob, "video.mkv");
      //   // console.log("state.videoStream", state.videoStream);
      //   state.videoRef.src = blobURL;
      // });
      // state.videoStream.getTracks().forEach((track) => track.stop());
      // state.isRecord = false;
      // state.isPaused = false;
      // // RecordRTC.invokeSaveAsDialog(state.recorder.getBlob(), "video.webm");
      /*---------------------初始写法---------------------*/
      state.recorder.stopRecording((blobURL: any) => {
        RecordRTC.getSeekableBlob(
          state.recorder.getBlob(),
          (seekableBlob: any) => {
            console.log("seekableBlob", seekableBlob);
            state.videoRef.src = blobURL;
            RecordRTC.invokeSaveAsDialog(seekableBlob, "video.mkv");
          }
        );
      });
      state.videoStream.getTracks().forEach((track) => track.stop());
      state.isRecord = false;
      state.isPaused = false;
    };

    // 检测浏览器是否支持屏幕录制的api
    if (!navigator.mediaDevices.getDisplayMedia) {
      let error = "您的浏览器不支持屏幕录制！";
      throw new Error(error);
    }

    // const invokeGetDisplayMedia = (
    //   success: ((value: MediaStream) => any) | null | undefined,
    //   error: ((value: MediaStream) => any) | null | undefined
    // ) => {
    //   let displayMediaStreamConstraints = { video: true };
    //   if (navigator.mediaDevices.getDisplayMedia) {
    //     navigator.mediaDevices
    //       .getDisplayMedia(displayMediaStreamConstraints)
    //       .then(success)
    //       .catch(error);
    //   }
    // };

    const addStreamStopListener = (stream: any, callback: any) => {
      stream.addEventListener(
        "ended",
        () => {
          console.log("ended");
          callback();
          callback = () => {};
        },
        false
      );
      stream.addEventListener(
        "inactive",
        () => {
          console.log("inactive");
          callback();
          callback = () => {};
        },
        false
      );
      stream.getTracks().forEach((track: any) => {
        track.addEventListener(
          "ended",
          () => {
            console.log("track ended");
            callback();
            callback = () => {};
          },
          false
        );
        track.addEventListener(
          "inactive",
          () => {
            console.log("track inactive");

            callback();
            callback = () => {};
          },
          false
        );
      });
    };

    // const captureScreen = (callback) => {
    //   invokeGetDisplayMedia(
    //     (screen) => {
    //       addStreamStopListener(screen, () => {
    //         //
    //       });
    //       callback(screen);
    //     },
    //     (error) => {
    //       console.log(error);
    //       alert(
    //         "Unable to capture your screen.Please check console logs.\n" + error
    //       );
    //     }
    //   );
    // };

    // // 开始录制
    // const startRecord = () => {
    //   captureScreen((screen: MediaProvider | null) => {
    //     state.videoRef.srcObject = screen;
    //     state.recorder = RecordRTC(screen, {
    //       type: "video",
    //       mimeType: "video/webm;codecs=vp8",
    //       disableLogs: false,
    //       getNativeBlob: false,
    //     });
    //     state.recorder.startRecording();
    //     // release screen on stopRecording
    //     state.recorder.screen = screen;
    //     state.isRecord = true;
    //   });
    // };

    // const stopRecordCallBack = () => {
    //   state.videoRef.src = state.videoRef.srcObject = null;
    //   state.videoRef.src = URL.createObjectURL(state.recorder.getBlob());
    //   state.recorder.screen.stop();
    //   state.recorder.destroy();
    //   state.recorder = null;
    //   state.isRecord = false;
    // };

    const playRecord = () => {
      state.videoRef.src =
        "blob:http://localhost:8080/dcf80c5a-def3-4105-a450-8d6a36505da8";
      state.recorder.reset();
    };

    // 截图
    const screenshot = () => {
      state.canvasRef.setAttribute("width", state.videoRef.offsetWidth + "");
      state.canvasRef.setAttribute("height", state.videoRef.offsetHeight + "");
      state.canvasRef
        .getContext("2d")
        .drawImage(
          state.videoRef,
          0,
          0,
          state.canvasRef.offsetWidth,
          state.canvasRef.offsetHeight
        );
      let url = state.canvasRef.toDataURL("image/jpeg");
      console.log("url", url);
    };

    return {
      ...toRefs(state),
      startRecord,
      pauseRecord,
      stopRecord,
      playRecord,
      screenshot,
    };
  },
});
</script>
    
<style scoped>
.layout_one {
  background: #fff;
  padding: 20px;
  height: calc(100vh - 140px);
  box-shadow: 0 0 3px #e4e7ed;
}
.layout_one:hover {
  box-shadow: 0 0 5px #cdd0d6;
}
</style>